import Clipboard from 'clipboard'

/**
 * 获取对象中的值
 * @param obj
 * @param key
 * @returns  返回对象中的值
 */
const getValueFromKey = <T, K extends keyof T>(obj: T, key: K): T[K] => obj[key]

/**
 * 校验手机号
 * @param data
 * @returns 校验后的结果
 */
const validPhone = (data: string): boolean => /^1[3-9]\d{9}$/.test(data)

/**
 * 校验身份证
 * @param data
 * @returns 校验后的结果
 */
function validCard(data: string): boolean {
  const reg = /^[1-9]\d{7}(?:0\d|1[0-2])(?:[0|12]\d|3[01])\d{3}$|^[1-9]\d{5}[1-9]\d{3}(?:0\d|1[0-2])(?:[0|12]\d|3[01])\d{3}[0-9X]$/i
  return reg.test(data)
}

/**
 * 验证邮箱
 * @param  data
 * @returns 校验后的结果
 */
function validateEmail(data: string): boolean {
  const re = /^[\w\-.]+@[0-9a-z]+\.[a-z]{2,3}(?:\.[a-z]{2})?$/
  return re.test(data)
}

/**
 * 验证 QQ
 * 1 首位不能是0  ^[1-9]
 * 2 必须是 [5, 11] 位的数字  \d{4,9}
 * @param {string} data
 * @returns 校验后的结果
 */
function validateQQ(data: string): boolean {
  const re = /^[1-9]\d{4,9}$/
  return re.test(data)
}

/**
 * @function
 * @description 复制
 * @param copyParams
 * @param {string} copyParams.text 复制的文本
 * @param {string} copyParams.el 复制的元素, 默认复制元素.copy
 * @param {boolean} copyParams.needToast 是否提示
 * @param {string} copyParams.successText 成功的文本
 * @param {string} copyParams.failText 失败的文本
 */
function copy({ text, el = '.copy', needToast, successText, failText }: { text: string; el?: string; needToast?: boolean; successText?: string; failText?: string }) {
  const clipboard = new Clipboard(el, {
    text() {
      return text
    }
  })
  clipboard.on('success', (e: Clipboard.Event) => {
    if (needToast) {
      console.log(successText || e.text || '复制成功')
    }

    // 释放内存
    clipboard.destroy()
  })
  clipboard.on('error', (e: Clipboard.Event) => {
    console.log(e.text)
    // 不支持复制
    if (needToast) {
      console.log(failText || e.text || '复制失败')
    }

    // 释放内存
    clipboard.destroy()
  })
}

/**
 * 格式化手机号
 * @param {string} data
 * @returns 150****3333
 */
function formatPhone(data: string): string {
  const reg = /^(\d{3})\d{4}(\d{4})$/
  return data.replace(reg, '$1****$2')
}

/**
 * 格式化身份证号 4**4
 * @param data
 * @returns 返回格式后的数据
 */
function formatIdCard(data: string): string {
  if (data.length <= 2) {
    return data
  }

  const len = data.length - 2
  let str = data[0]
  const lastStr = data[data.length - 1]
  for (let i = 0; i < len; i++) {
    str += '*'
  }
  str += lastStr
  return str
}

/**
 * 获取字符长度
 * @param  data
 * @returns 返回字符长度
 */
const getStrLength = (data: string): number => data.replace(/[^\u0000-\u00FF]/g, 'aa').length

/**
 * 判断是否是中文
 * @param data
 * @returns 返回结果
 */
function isChineseChar(data: string): boolean {
  const reg = /[\u4E00-\u9FA5\uF900-\uFA2D]/
  return reg.test(data)
}

/**
 * 精度计算
 * @param  data 计算的数值
 * @param  type 乘除
 * @returns 返回计算后的结果
 */
function precision(data: number, type = 'multiplication'): string | number {
  // 处理Infinity的情况
  if (!Number.isFinite(data)) {
    throw new TypeError('Input number must be finite')
  }

  const unit = 100
  const str = data.toString()
  if (!str.includes('.')) {
    return type === 'multiplication' ? data * unit : data / unit
  }

  const strArr: string[] = str.split('.')
  let result: number | string = ''
  if (type === 'multiplication') {
    if (strArr[1].length === unit.toString().length - 1) {
      result = Number(strArr[0]) === 0 ? strArr[1] : Number(strArr[0]) + Number(strArr[1])
    } else if (strArr[1].length < unit.toString().length - 1) {
      result = Number(strArr[0]) === 0 ? strArr[1] : Number(strArr[0]) + Number(strArr[1]) * 10
    } else if (strArr[1].length > unit.toString().length - 1) {
      let newUnit = '1'
      for (let index = 0; index < strArr[1].length - 2; index++) {
        newUnit += '0'
      }

      result = Number(strArr[0]) === 0 ? Number(strArr[1]) / Number(newUnit) : Number(strArr[0]) + Number(strArr[1]) / Number(newUnit)
    }
  } else {
    return Number(strArr[0]) === 0 ? `0.00${strArr[1]}` : Number(strArr[0]) / unit + Number(strArr[1])
  }

  return result
}

export { copy, formatIdCard, formatPhone, getStrLength, getValueFromKey, isChineseChar, precision, validateEmail, validateQQ, validCard, validPhone }
